<template>
  <div>
    <el-dialog
      title="项目位置"
      v-model="state.dialogVisible"
      width="782px"
      class="assetsAddressdialogPage "
      center
      :close-on-click-modal="false"
    
    >
      <div class="searchBox">
        <el-input
          v-model="state.searchAddrInput"
          id="mapInput"
          style="width: 60%;height: 30px"
          placeholder="请输入搜索详细地址"
          class="searchInputStyle"
          clearable
        />
        <div id="mapPanel" class="searchMapPanelStyle"></div>
      </div>
      <div class="mapBox" style="height:500px">
        <BaseMap @getMap="getTheMap" idName="assetFile-map" />
      </div>
      <div class="footBox">
        <el-input
          v-model="state.address"
          class="addrInputBox"
          placeholder="请在地图选定项目位置"
          clearable
          @change="addrChange"
        >
        </el-input>
        <el-button
          plain
          color="#FF7B50"
          style="margin-right: 8px"
          @click="setMapMark"
          >地图选点</el-button
        >
        <el-button
          color="#F12527"
          style="color: #fff; width: 88px; height: 40px"
          type="primary"
          @click="submitAddr"
        >
          提交</el-button
        >
      </div>
    </el-dialog>
  </div>
  </template>
  
  <script setup>
  import { onMounted, reactive, ref } from "vue";
  import { ElDialog, ElMessage } from "element-plus";
  import BaseMap from "@/components/BaseMap";
  
  const state = reactive({
    dialogVisible: false,
    searchAddrInput: "",
    getMapPointObj: {
      lng: "",
      lat: "",
    },
    myValue: "",
    address: "",
    province: "",
    city: "",
    district: "",
  });
  
  const mapState = reactive({
    theMap: null,
    markTool: null,
    autoComplet: null,
    localSearch: null,
  });
  
  // 获取地图实例
  const getTheMap = (map) => {
    mapState.theMap = map;
    // 创建一个自动完成的对象
    mapState.autoComplet = new BMap.Autocomplete({
      input: "mapInput",
      location: mapState.theMap,
    });
    searchAddrFn();
  };
  
  // 初始给地图添加标记
  const initMark = (lng, lat) => {
    mapState.theMap.clearOverlays();
    let newPoint = new BMap.Point(lng, lat);
    mapState.theMap.centerAndZoom(newPoint, 15);
    let newMarker = new BMap.Marker(newPoint);
    mapState.theMap.addOverlay(newMarker);
  };
  
  // 地图选点
  const setMapMark = () => {
    // 地图上添加标注类，实现点击地图添加点标注
    mapState.markTool = new BMapLib.MarkerTool(mapState.theMap, {
      followText: "选择地点",
      autoClose: true,
    });
    // 开启添加点标注状态
    mapState.markTool.open();
    mapState.markTool.addEventListener("markend", function (e) {
      state.searchAddrInput = "";
      mapState.theMap.clearOverlays();
      let theLng = e.marker.point.lng;
      let theLat = e.marker.point.lat;
      state.getMapPointObj.lng = e.marker.point.lng;
      state.getMapPointObj.lat = e.marker.point.lat;
      let newPoint = new BMap.Point(theLng, theLat);
      mapState.theMap.centerAndZoom(newPoint, 15);
      let newMarker = new BMap.Marker(newPoint);
      mapState.theMap.addOverlay(newMarker);
      getPointAddr(theLng, theLat);
    });
  };
  // 根据坐标，逆地址解析坐标地址
  const getPointAddr = (lng, lat) => {
    let geoc = new BMap.Geocoder();
    let getPoint = new BMap.Point(lng, lat);
    geoc.getLocation(getPoint, function (rs) {
      state.province = rs.addressComponents.province;
      state.city = rs.addressComponents.city;
      state.district = rs.addressComponents.district;
      if (rs.address !== "") {
        state.address = rs.address;
      } else {
        if (rs.addressComponents.district) {
          state.address =
            rs.addressComponents.province +
            rs.addressComponents.city +
            rs.addressComponents.district;
        } else {
          state.address =
            rs.addressComponents.province + rs.addressComponents.city;
        }
      }
    });
  };
  
  // 主动修改地址
  const addrChange = (val) => {
    if (val) {
      if (val.indexOf("市") == -1) {
        ElMessage({
          type: "error",
          message: "地址中需要包含市、区(县)信息",
        });
      } else {
        getAddrPoint(val);
      }
    }
  };
  
  // 根据输入地址，标记地址位置点
  const getAddrPoint = (addr) => {
    let geoc = new BMap.Geocoder();
    // 将地址解析结果显示在地图上，并调整地图视野
    geoc.getPoint(addr, function (point) {
      if (point) {
        console.log(point);
        mapState.theMap.centerAndZoom(point, 15);
        mapState.theMap.addOverlay(new BMap.Marker(point));
        state.getMapPointObj.lng = point.lng;
        state.getMapPointObj.lat = point.lat;
      } else {
        ElMessage({
          type: "error",
          message: "您的地址没有解析到结果！",
        });
      }
    });
  };
  
  const myFun = () => {
    //获取第一个智能搜索的结果
    let pp = mapState.localSearch.getResults().getPoi(0).point;
    mapState.theMap.centerAndZoom(pp, 18);
    initMark(pp.lng, pp.lat);
    state.getMapPointObj.lng = pp.lng;
    state.getMapPointObj.lat = pp.lat;
  
    // 输入框选择地址，在地址前加上省份
    let geoc = new BMap.Geocoder();
    let getPoint = new BMap.Point(pp.lng, pp.lat);
    geoc.getLocation(getPoint, function (rs) {
      if (state.myValue.indexOf("省") == -1) {
        state.address = rs.addressComponents.province + state.myValue;
      } else {
        state.address = state.myValue;
      }
    });
  };
  const setPlace = () => {
    //智能搜索
    mapState.localSearch = new BMap.LocalSearch(mapState.theMap, {
      onSearchComplete: myFun,
    });
    mapState.localSearch.search(state.myValue);
  };
  
  // 地址搜索框
  const searchAddrFn = () => {
    // 鼠标放在下拉列表上的事件
    mapState.autoComplet.addEventListener("onhighlight", function (e) {
      let str = "";
      let _value = e.fromitem.value;
      let value = "";
      if (e.fromitem.index > -1) {
        value =
          _value.province +
          _value.city +
          _value.district +
          _value.street +
          _value.business;
      }
      str = "FromItem<br/>index = " + e.fromitem.index + "<br/>value = " + value;
  
      value = "";
      if (e.toitem.index > -1) {
        _value = e.toitem.value;
        value =
          _value.province +
          _value.city +
          _value.district +
          _value.street +
          _value.business;
      }
      str +=
        "<br />ToItem<br />index = " + e.toitem.index + "<br />value = " + value;
      document.getElementById("mapPanel").innerHTML = str;
    });
  
    //鼠标点击下拉列表后的事件
    mapState.autoComplet.addEventListener("onconfirm", function (e) {
      let _value = e.item.value;
      state.myValue =
        _value.province +
        _value.city +
        _value.district +
        _value.street +
        _value.business;
      document.getElementById("mapPanel").innerHTML =
        "onconfirm<br />index = " +
        e.item.index +
        "<br />myValue = " +
        state.myValue;
  
      setPlace();
    });
  };
  
  // 开启弹窗，父组件中调用
  const openMap = () => {
    state.dialogVisible = true;
  };
  
  // 向父组件传值
  const emits = defineEmits(["getMapAddrInfo"]);
  const submitAddr = () => {
    let mapInfoObj = {
      lng: state.getMapPointObj.lng,
      lat: state.getMapPointObj.lat,
      address: state.address
    }
    emits("getMapAddrInfo", mapInfoObj);
    state.dialogVisible = false
  }
  
  // 必须放在最后
  defineExpose({ openMap });
  </script>
  
  <style lang="scss" scoped>
  .assetsAddressdialogPage {
    .mapBox {
      width: 100%;
      // height: 500px;
      margin-bottom: 23px;
    }
    .searchBox {
      .searchInputStyle {
        margin-bottom: 16px;
        // width: 60%;
        // height: 40px;
        // margin: auto;
        // border: 1px solid #dddee1;
        // border-radius: 4px;
        // padding: 0 10px;
      }
    }
    .footBox {
      .addrInputBox {
        width: 60%;
        margin-right: 12px;
      }
    }
  }
  </style>
  <style lang="scss" scoped>
  :deep(.assetsAddressdialogPage) {
    .el-dialog__header {
      padding-top: 18px;
      padding-bottom: 0;
      .el-dialog__title {
        font-size: 16px;
        font-weight: 500;
        color: #1a1a1a;
        font-family: SourceHanSansMedium;
      }
    }
  }
  </style>
 
  